from PyQt5.QtCore import QRegExp, Qt
from PyQt5.QtGui import QRegExpValidator
from PyQt5.QtWidgets import QFormLayout, QLineEdit, QDialogButtonBox, QMessageBox, QDialog, QCheckBox, QHBoxLayout, \
    QPushButton, QComboBox, QVBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView, QItemDelegate, QLabel, \
    QStyledItemDelegate


class ComboBoxDelegate(QStyledItemDelegate):
    '''
    设置下拉框每行的高度
    '''
    def __init__(self, parent=None):
        super().__init__(parent)

    def sizeHint(self, option, index):
        size = super().sizeHint(option, index)
        size.setHeight(40)  # 设置行高为40，调整你想要的行高
        return size

class AddStoreDialog(QDialog):
    def __init__(self, db, parent=None):
        super().__init__(parent)
        self.db = db
        self.setWindowTitle("新增店铺")

        # 获取主窗口的几何信息
        parent_geometry = parent.geometry()  # 获取父窗口的几何范围
        dialog_width = 300
        dialog_height = 250

        # 计算弹出框在主窗口中心的位置
        x = parent_geometry.x() + (parent_geometry.width() - dialog_width) // 2
        y = parent_geometry.y() + (parent_geometry.height() - dialog_height) // 2

        # 设置弹出框的位置和大小，使其出现在主窗口的中央
        self.setGeometry(x, y, dialog_width, dialog_height)

        layout = QFormLayout()

        # 添加表单控件和按钮
        self.storeNameEdit = QLineEdit(self)
        self.usernameEdit = QLineEdit(self)
        self.passwordEdit = QLineEdit(self)
        self.passwordEdit.setEchoMode(QLineEdit.Password)

        # 激活标识的复选框
        self.activeFlagCheckBox = QCheckBox("数据获取标识", self)

        layout.addRow('店铺名称:', self.storeNameEdit)
        layout.addRow('用户名:', self.usernameEdit)
        layout.addRow('密码:', self.passwordEdit)
        layout.addRow(self.activeFlagCheckBox)  # 加入复选框

        button_layout = QHBoxLayout()
        save_btn = QPushButton("保存")
        cancel_btn = QPushButton("取消")
        save_btn.clicked.connect(self.saveStore)
        cancel_btn.clicked.connect(self.reject)

        button_layout.addWidget(save_btn)
        button_layout.addWidget(cancel_btn)

        layout.addRow(button_layout)
        self.setLayout(layout)

    def saveStore(self):
        store_name = self.storeNameEdit.text()
        username = self.usernameEdit.text()
        password = self.passwordEdit.text()
        active_flag = self.activeFlagCheckBox.isChecked()

        if store_name:
            try:
                # 调用 DBManager 的 insert_or_update_store 方法来新增或更新店铺
                self.db.insert_or_update_store(store_name, username, password, active_flag)
                self.accept()  # 关闭对话框
            except Exception as e:
                QMessageBox.warning(self, '错误', f'保存店铺时出错: {str(e)}')
        else:
            QMessageBox.warning(self, '警告', '请填写完整的店铺信息')


class EditStoreDialog(QDialog):
    def __init__(self, db, parent=None):
        super().__init__(parent)
        self.db = db
        self.setWindowTitle("修改店铺")
        self.setFixedSize(300, 250)

        # 居中显示
        if parent:
            parent_geometry = parent.geometry()
            x = parent_geometry.x() + (parent_geometry.width() - self.width()) // 2
            y = parent_geometry.y() + (parent_geometry.height() - self.height()) // 2
            self.setGeometry(x, y, self.width(), self.height())
            self.setStyleSheet(parent.styleSheet())

        # 获取所有店铺
        self.store_map = {row['store_name']: row for row in self.db.get_all_stores_dict()}
        self.store_names = list(self.store_map.keys())

        # 下拉框选择店铺
        self.storeCombo = QComboBox(self)
        self.storeCombo.setItemDelegate(ComboBoxDelegate())  # 设置下拉项行高
        self.storeCombo.addItems(self.store_names)
        self.storeCombo.setCurrentIndex(0)
        self.storeCombo.currentTextChanged.connect(self.load_store_info)

        # 表单控件
        self.storeNameEdit = QLineEdit(self)
        self.storeNameEdit.setReadOnly(True)

        self.usernameEdit = QLineEdit(self)
        self.passwordEdit = QLineEdit(self)
        # self.passwordEdit.setEchoMode(QLineEdit.Password)

        self.activeFlagCheck = QCheckBox("数据获取标识", self)

        # 表单布局
        formLayout = QFormLayout()
        formLayout.addRow("选择店铺:", self.storeCombo)
        formLayout.addRow("店铺名称:", self.storeNameEdit)
        formLayout.addRow("用户名:", self.usernameEdit)
        formLayout.addRow("密码:", self.passwordEdit)
        formLayout.addRow("", self.activeFlagCheck)

        # 按钮区
        buttonBox = QDialogButtonBox(self)
        saveButton = buttonBox.addButton("保存", QDialogButtonBox.AcceptRole)
        cancelButton = buttonBox.addButton("取消", QDialogButtonBox.RejectRole)
        deleteButton = buttonBox.addButton("删除", QDialogButtonBox.DestructiveRole)

        saveButton.clicked.connect(self.saveStore)
        cancelButton.clicked.connect(self.reject)
        deleteButton.clicked.connect(self.deleteStore)

        # 总体布局
        layout = QVBoxLayout()
        layout.addLayout(formLayout)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

        # 初始加载第一个店铺信息
        if self.store_map:
            first_store_name = list(self.store_map.keys())[0]
            self.load_store_info(first_store_name)

    def load_store_info(self, store_name):
        store_info = self.store_map.get(store_name, {})
        self.storeNameEdit.setText(store_info.get('store_name', ''))
        self.usernameEdit.setText(store_info.get('username', ''))
        self.passwordEdit.setText(store_info.get('password', ''))
        self.activeFlagCheck.setChecked(bool(store_info.get('flag', True)))

    def saveStore(self):
        store_name = self.storeCombo.currentText()
        username = self.usernameEdit.text()
        password = self.passwordEdit.text()
        flag = self.activeFlagCheck.isChecked()

        if store_name:
            self.db.insert_or_update_store(store_name, username, password, flag)
            self.accept()
        else:
            QMessageBox.warning(self, '警告', '请填写完整的店铺信息')

    def deleteStore(self):
        store_name = self.storeCombo.currentText()

        msg = QMessageBox(self)
        msg.setWindowTitle("确认删除")
        msg.setText(f'确定要删除店铺 "{store_name}" 吗？此操作不可恢复。')

        yes_btn = msg.addButton("是", QMessageBox.YesRole)
        no_btn = msg.addButton("否", QMessageBox.NoRole)
        msg.exec_()

        if msg.clickedButton() == yes_btn:
            self.db.delete_store(store_name)
            self.accept()


# 新增商品弹出框
class AddProductDialog(QDialog):
    def __init__(self, db, parent=None):
        super().__init__(parent)
        self.db = db
        self.setWindowTitle("新增商品")
        dialog_width = 300
        dialog_height = 250

        # 居中显示弹窗
        if parent:
            parent_geometry = parent.geometry()
            x = parent_geometry.x() + (parent_geometry.width() - dialog_width) // 2
            y = parent_geometry.y() + (parent_geometry.height() - dialog_height) // 2
            self.setStyleSheet(parent.styleSheet())
        else:
            x, y = 100, 100  # 默认位置

        self.setGeometry(x, y, dialog_width, dialog_height)

        layout = QFormLayout()

        # 商品信息输入框
        self.productIDEdit = QLineEdit(self)
        # 使用正则表达式验证器，只允许输入数字
        regex = QRegExp(r'^[0-9]+$')  # 只允许正整数
        validator = QRegExpValidator(regex)
        self.productIDEdit.setValidator(validator)

        self.productDescEdit = QLineEdit(self)

        # 所属店铺下拉框
        self.storeCombo = QComboBox(self)
        self.storeCombo.setItemDelegate(ComboBoxDelegate())  # 设置下拉项行高
        stores_list = self.db.get_all_stores_dict()

        # 获取店铺名称并添加到下拉框中
        store_names = [store['store_name'] for store in stores_list]
        self.storeCombo.addItems(store_names)

        self.activeFlagCheckBox = QCheckBox("数据获取标识", self)

        layout.addRow('商品ID:', self.productIDEdit)
        layout.addRow('商品描述:', self.productDescEdit)
        layout.addRow('所属店铺:', self.storeCombo)
        layout.addRow(self.activeFlagCheckBox)

        # 按钮布局
        button_layout = QHBoxLayout()
        save_btn = QPushButton("保存")
        cancel_btn = QPushButton("取消")
        save_btn.clicked.connect(self.saveProduct)
        cancel_btn.clicked.connect(self.reject)
        button_layout.addWidget(save_btn)
        button_layout.addWidget(cancel_btn)

        layout.addRow(button_layout)
        self.setLayout(layout)

    def saveProduct(self):
        product_id = self.productIDEdit.text()
        product_desc = self.productDescEdit.text()
        store_name = self.storeCombo.currentText()
        flag = self.activeFlagCheckBox.isChecked()

        if not all([product_id, store_name]):
            QMessageBox.warning(self, "警告", "请填写完整的商品ID和所属店铺信息")
            return

        # 保存到数据库
        self.db.insert_or_update_product(product_id, product_desc, store_name, flag)
        self.accept()

# 编辑商品弹出框
class EditProductDialog(QDialog):
    def __init__(self, db, parent=None):
        super().__init__(parent)
        self.db = db
        self.setWindowTitle("修改商品")
        dialog_width = 900
        dialog_height = 750

        # 居中显示弹窗
        if parent:
            parent_geometry = parent.geometry()
            x = parent_geometry.x() + (parent_geometry.width() - dialog_width) // 2
            y = parent_geometry.y() + (parent_geometry.height() - dialog_height) // 2
            self.setStyleSheet(parent.styleSheet())
        else:
            x, y = 100, 100

        self.setGeometry(x, y, dialog_width, dialog_height)

        # 获取所有店铺名称
        stores = self.db.get_all_stores_dict()
        self.store_names = [store['store_name'] for store in stores]

        # 店铺下拉框
        self.storeComboBox = QComboBox(self)
        self.storeComboBox.setItemDelegate(ComboBoxDelegate())  # 设置下拉项行高
        self.storeComboBox.addItems(self.store_names)
        self.storeComboBox.setCurrentIndex(0)
        self.storeComboBox.currentTextChanged.connect(self.updateProductTable)

        self.productTable = QTableWidget(self)
        self.productTable.setColumnCount(5)
        self.productTable.setHorizontalHeaderLabels(['选择', '商品ID', '商品描述', '店铺名称', '标志'])

        # 设置商品描述列 Stretch 拉伸
        header = self.productTable.horizontalHeader()
        header.setSectionResizeMode(2, QHeaderView.Stretch)

        layout = QVBoxLayout()
        layout.addWidget(QLabel('请选择店铺:'))
        layout.addWidget(self.storeComboBox)
        layout.addWidget(self.productTable)

        # 按钮区域
        buttonBox = QDialogButtonBox(self)
        saveButton = buttonBox.addButton("保存", QDialogButtonBox.AcceptRole)
        cancelButton = buttonBox.addButton("取消", QDialogButtonBox.RejectRole)
        deleteButton = buttonBox.addButton("删除", QDialogButtonBox.DestructiveRole)

        saveButton.clicked.connect(self.saveProduct)
        cancelButton.clicked.connect(self.reject)
        deleteButton.clicked.connect(self.deleteSelectedProducts)

        layout.addWidget(buttonBox)
        self.setLayout(layout)

        self.updateProductTable(self.store_names[0])

    def updateProductTable(self, store_name):
        self.products = self.db.get_products_by_store(store_name)
        self.productTable.setRowCount(len(self.products))

        for row, product in enumerate(self.products):
            # 复选框（不默认勾选）
            checkbox_item = QTableWidgetItem()
            checkbox_item.setCheckState(Qt.Unchecked)
            self.productTable.setItem(row, 0, checkbox_item)

            # 商品ID（只读）
            id_item = QTableWidgetItem(product['product_id'])
            id_item.setFlags(id_item.flags() ^ Qt.ItemIsEditable)
            self.productTable.setItem(row, 1, id_item)

            # 商品描述 + Tooltip
            desc_item = QTableWidgetItem(product['description'])
            desc_item.setToolTip(product['description'])
            self.productTable.setItem(row, 2, desc_item)

            # 店铺名（只读）
            store_item = QTableWidgetItem(product['store_name'])
            store_item.setFlags(store_item.flags() ^ Qt.ItemIsEditable)
            self.productTable.setItem(row, 3, store_item)

            # 标志
            flag_item = QTableWidgetItem("是" if product['flag'] else "否")
            self.productTable.setItem(row, 4, flag_item)

        # 自动调整列宽
        self.productTable.resizeColumnsToContents()

    def saveProduct(self):
        updated_rows = []
        try:
            for row in range(self.productTable.rowCount()):
                product_id = self.productTable.item(row, 1).text().strip()
                description = self.productTable.item(row, 2).text().strip()
                store_name = self.productTable.item(row, 3).text().strip()
                flag_text = self.productTable.item(row, 4).text().strip()
                flag = True if flag_text == '是' else False

                # 原始数据对比，只保存修改的行
                original = self.products[row]
                if (description != original['description'] or flag != original['flag']):
                    updated_rows.append((product_id, description, store_name, flag))

            if not updated_rows:
                QMessageBox.information(self, "提示", "无变动，未保存任何商品信息")
                return

            # 批量更新
            self.db.batch_update_products(updated_rows)
            QMessageBox.information(self, "提示", f"已保存 {len(updated_rows)} 条商品信息！")

            # 更新内存缓存，避免重复提交
            self.updateProductTable(self.storeComboBox.currentText())

        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存失败：{str(e)}")

    def deleteSelectedProducts(self):
        selected_rows = []
        for row in range(self.productTable.rowCount()):
            checkbox_item = self.productTable.item(row, 0)
            if checkbox_item and checkbox_item.checkState() == Qt.Checked:
                selected_rows.append(row)

        if not selected_rows:
            QMessageBox.warning(self, "警告", "请先选择要删除的商品")
            return

        reply = QMessageBox.question(
            self, "确认删除", "确定要删除选中的商品吗？此操作不可恢复。",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )

        if reply == QMessageBox.Yes:
            for row in sorted(selected_rows, reverse=True):  # 倒序删除防止行号错乱
                product_id = self.productTable.item(row, 1).text()
                self.db.delete_product(product_id)
                self.productTable.removeRow(row)